<template>
  <div class="carousel-wrapper">
    <div class="carousel-viewport" :style="{ height: `${height}px` }" ref="carouselViewport">
      <div class="carousel-container">
        <div 
          v-for="(item, index) in slides" 
          :key="index" 
          class="carousel-item"
          :class="{ 'active': currentIndex === index }"
          :style="getItemStyle(index)"
          @click="onSlideClick(item, index)"
        >
          <img :src="item.coverImg" :alt="item.title" class="carousel-image" />
          <div v-if="showCaption && item.title" class="carousel-caption">
            {{ item.title }}
          </div>
        </div>
      </div>
      
      <button v-if="showArrows" class="carousel-arrow prev" :class="{ 'visible': arrowsVisible }" @click="prevSlide">
        <GIcon name="gt-plane-left" />
      </button>
      <button v-if="showArrows" class="carousel-arrow next" :class="{ 'visible': arrowsVisible }" @click="nextSlide">
        <GIcon name="gt-plane-right" />
      </button>
    </div>
    
    <div v-if="showIndicators" class="carousel-indicators">
      <span 
        v-for="(_, index) in slides"
        :key="index"
        :class="['indicator-dot', { 'active': currentIndex === index }]"
        @click="goToSlide(index)"
      ></span>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';

  interface CarouselSlide {
    coverImg: string;
    title?: string;
    [key: string]: any;
  }

  const props = defineProps({
    slides: {
      type: Array as () => CarouselSlide[],
      required: true
    },
    height: {
      type: Number,
      default: 320
    },
    autoplay: {
      type: Boolean,
      default: true
    },
    autoplayInterval: {
      type: Number,
      default: 3000
    },
    showArrows: {
      type: Boolean,
      default: true
    },
    showIndicators: {
      type: Boolean,
      default: true
    },
    showCaption: {
      type: Boolean,
      default: false
    },
    initialIndex: {
      type: Number,
      default: 0
    }
  });

  const emit = defineEmits(['slide-click', 'slide-change']);
  
  const carouselViewport = ref(null);
  const currentIndex = ref(props.initialIndex);
  const arrowsVisible = ref(false);
  let autoplayTimer: any = null;

  // 监听初始索引变化
  watch(() => props.initialIndex, (newValue) => {
    if (newValue >= 0 && newValue < props.slides.length) {
      currentIndex.value = newValue;
    }
  });

  // 计算每个轮播项的样式
  const getItemStyle = (index: number) => {
    const totalItems = props.slides.length;
    const indexDiff = (index - currentIndex.value + totalItems) % totalItems;
  
    // 计算位置：-1=左侧，0=中间，1=右侧，其他=隐藏
    let position;
    if (indexDiff === 0) position = 0; // 中间
    else if (indexDiff === 1 || indexDiff === totalItems - 1) {
      position = indexDiff === 1 ? 1 : -1; // 右侧或左侧
    } else {
      position = null; // 隐藏
    }
  
    // 如果不在可见范围内，隐藏但保留在DOM中
    if (position === null) {
      return { 
        opacity: 0,
        visibility: 'hidden',
        transform: 'scale(0.8)',
        zIndex: 0
      };
    }
  
    const zIndex = position === 0 ? 3 : 1; // 中间层级最高
    const scale = position === 0 ? 1 : 0.9; // 中间大小为100%，两侧为90%

    if (position === -1) {
      // 左侧项
      return {
        opacity: 1,
        visibility: 'visible',
        transform: `scale(${scale})`,
        zIndex: zIndex,
        left: '-2%',
        right: 'auto'
      };
    } else if (position === 0) {
      // 中间项
      return {
        opacity: 1,
        visibility: 'visible',
        transform: `translateX(-50%) scale(${scale})`,
        zIndex: zIndex,
        left: '50%',
        right: 'auto'
      };
    } else {
      // 右侧项
      return {
        opacity: 1,
        visibility: 'visible',
        transform: `scale(${scale})`,
        zIndex: zIndex,
        left: 'auto',
        right: '-2%'
      };
    }
  };

  // 滚动到指定幻灯片
  const goToSlide = (index: number) => {
    if (index !== currentIndex.value) {
      currentIndex.value = index;
      emit('slide-change', index);
    }
  };

  // 下一张幻灯片
  const nextSlide = () => {
    goToSlide((currentIndex.value + 1) % props.slides.length);
  };

  // 上一张幻灯片
  const prevSlide = () => {
    goToSlide((currentIndex.value - 1 + props.slides.length) % props.slides.length);
  };

  // 点击幻灯片
  const onSlideClick = (slide: CarouselSlide, index: number) => {
    emit('slide-click', { slide, index });
  };

  // 启动自动播放
  const startAutoplay = () => {
    if (!props.autoplay) return;
    
    stopAutoplay();
    autoplayTimer = setInterval(() => {
      nextSlide();
    }, props.autoplayInterval);
  };

  // 停止自动播放
  const stopAutoplay = () => {
    if (autoplayTimer) {
      clearInterval(autoplayTimer);
      autoplayTimer = null;
    }
  };

  // 暂停和恢复自动播放
  const pauseAutoplay = () => {
    stopAutoplay();
  };

  const resumeAutoplay = () => {
    if (props.autoplay) {
      startAutoplay();
    }
  };

  // 处理鼠标悬停显示箭头,停止轮播
  const showArrowsOnHover = () => {
    arrowsVisible.value = true;
    pauseAutoplay();
  };

  const hideArrowsOnLeave = () => {
    arrowsVisible.value = false;
    resumeAutoplay();
  };

  onMounted(() => {
    startAutoplay();
    
    // 鼠标悬停时显示箭头，暂停轮播
    if (carouselViewport.value) {
      const viewport = carouselViewport.value as HTMLElement;
      viewport.addEventListener('mouseenter', showArrowsOnHover);
      viewport.addEventListener('mouseleave', hideArrowsOnLeave);
    }
  });

  onBeforeUnmount(() => {
    stopAutoplay();
    
    // 移除箭头显示的事件监听器
    if (carouselViewport.value) {
      const viewport = carouselViewport.value as HTMLElement;
      viewport.removeEventListener('mouseenter', showArrowsOnHover);
      viewport.removeEventListener('mouseleave', hideArrowsOnLeave);
    }
  });

  // 暴露方法给父组件
  defineExpose({
    goToSlide,
    nextSlide,
    prevSlide,
    getCurrentIndex: () => currentIndex.value
  });
</script>

<style scoped>
.carousel-wrapper {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.carousel-viewport {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.carousel-container {
  position: relative;
  width: 100%;
  height: 100%;
  perspective: 1000px;
}

.carousel-item {
  position: absolute;
  top: 0;
  left: 50%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.5s cubic-bezier(0.25, 0.1, 0.25, 1); /* 使用更平滑的贝塞尔曲线 */
  cursor: pointer;
  width: calc(100% / 2 - 16px);
  will-change: transform, opacity;
  backface-visibility: hidden;
  transform-style: preserve-3d;
}

.carousel-item.active {
  z-index: 3;
}

.carousel-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
}

.carousel-caption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 12px;
  background: rgba(0, 0, 0, 0.6);
  color: white;
  text-align: center;
  font-size: 14px;
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
}

.carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.8);
  border: none;
  color: #333;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.carousel-arrow.visible {
  opacity: 1;
}

.carousel-arrow:hover {
  background-color: #fff;
}

.carousel-arrow.prev {
  left: 20px;
}

.carousel-arrow.next {
  right: 20px;
}

.carousel-indicators {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  gap: 8px;
}

.indicator-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #ddd;
  cursor: pointer;
  transition: all 0.3s ease;
}

.indicator-dot.active {
  width: 24px;
  border-radius: 4px;
  background-color: #666;
}

@media (max-width: 768px) {
  .carousel-item {
    width: 70%;
    transition: all 0.4s cubic-bezier(0.25, 0.1, 0.25, 1); /* 小屏幕时稍微加快过渡速度 */
  }
  .carousel-arrow.prev {
    left: 5px;
  }
  .carousel-arrow.next {
    right: 5px;
  }
}
</style>